use std::env;

use agent::generic::{create_agent, Provider as GenericProvider, ProviderConfig};
use common::compose::CallBox;
use thiserror::Error;

/// 翻译提供商枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Provider {
    /// DeepSeek AI
    DeepSeek,
    /// OpenAI
    OpenAI,
    /// Google Gemini
    Gemini,
}

impl Provider {
    /// 转换为 GenericProvider
    pub fn to_generic(&self) -> GenericProvider {
        match self {
            Provider::DeepSeek => GenericProvider::DeepSeek,
            Provider::OpenAI => GenericProvider::OpenAI,
            Provider::Gemini => GenericProvider::Gemini,
        }
    }

    /// 从字符串解析提供商
    pub fn from_str(s: &str) -> Result<Self, String> {
        match s.to_lowercase().as_str() {
            "deepseek" => Ok(Provider::DeepSeek),
            "openai" => Ok(Provider::OpenAI),
            "gemini" => Ok(Provider::Gemini),
            _ => Err(format!("Unsupported provider: {}", s)),
        }
    }
}

/// 翻译服务错误类型
#[derive(Error, Debug)]
pub enum TransProviderError {
    /// API 密钥未找到
    #[error("API key not found for provider: {0}")]
    ApiKeyNotFound(String),

    /// 不支持的提供商
    #[error("Unsupported provider: {0}")]
    UnsupportedProvider(String),

    /// 提供商错误
    #[error("Provider error: {0}")]
    ProviderError(String),

    /// 环境变量错误
    #[error("Environment variable error: {0}")]
    EnvError(#[from] env::VarError),

    /// 模型错误
    #[error("Model error: {0}")]
    ModelError(String),
}

/// 目标语言枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TargetLang {
    /// 英语 (English)
    En,
    /// 中文 (Chinese)
    Zh,
    /// 西班牙语 (Spanish)
    Es,
    /// 法语 (French)
    Fr,
    /// 德语 (German)
    De,
    /// 日语 (Japanese)
    Ja,
    /// 俄语 (Russian)
    Ru,
    /// 意大利语 (Italian)
    It,
    /// 葡萄牙语 (Portuguese)
    Pt,
    /// 韩语 (Korean)
    Ko,
    /// 阿拉伯语 (Arabic)
    Ar,
    /// 印地语 (Hindi)
    Hi,
}

impl TargetLang {
    /// 获取语言代码
    pub fn code(&self) -> &'static str {
        match self {
            TargetLang::En => "en",
            TargetLang::Zh => "zh",
            TargetLang::Es => "es",
            TargetLang::Fr => "fr",
            TargetLang::De => "de",
            TargetLang::Ja => "ja",
            TargetLang::Ru => "ru",
            TargetLang::It => "it",
            TargetLang::Pt => "pt",
            TargetLang::Ko => "ko",
            TargetLang::Ar => "ar",
            TargetLang::Hi => "hi",
        }
    }

    /// 获取语言名称
    pub fn name(&self) -> &'static str {
        match self {
            TargetLang::En => "English",
            TargetLang::Zh => "Chinese",
            TargetLang::Es => "Spanish",
            TargetLang::Fr => "French",
            TargetLang::De => "German",
            TargetLang::Ja => "Japanese",
            TargetLang::Ru => "Russian",
            TargetLang::It => "Italian",
            TargetLang::Pt => "Portuguese",
            TargetLang::Ko => "Korean",
            TargetLang::Ar => "Arabic",
            TargetLang::Hi => "Hindi",
        }
    }
}





/// 创建翻译 CallBox，根据不同的 provider_config 和 model
///
/// # 参数
///
/// * `provider_config` - 提供商配置
/// * `model` - 模型名称，如果为空则使用默认模型
/// * `target_lang` - 目标语言
///
/// # 示例
///
/// ```rust,no_run
/// use trans::trans_provider::{create_translator, TargetLang};
/// use agent::generic::ProviderConfig;
/// use common::compose::make_empty_ctx;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
///     let provider_config = ProviderConfig::OpenAI {
///         api_key: "your-api-key".to_string(),
///         base_url: None,
///         temperature: 0.3,
///         max_tokens: None,
///     };
///     let translator = create_translator(provider_config, "gpt-4", TargetLang::Zh);
///     let result = translator.run("Hello, world!".to_string(), make_empty_ctx()).await?;
///     println!("{}", result);
///     Ok(())
/// }
/// ```
pub fn create_translator(
    provider_config: ProviderConfig,
    model: &str,
    target_lang: TargetLang,
) -> CallBox<'static, String, String> {
    // 生成翻译提示词，使用英语
    let system_prompt = format!(
        r#"You are a professional translator. Follow these rules when translating text to {}:

1. DO NOT translate:
   - Code snippets and commands
   - File paths and URLs
   - Technical terms (e.g. Kubernetes, Docker, API, SDK)
   - Product names and brands
   - Environment variables
   - Version numbers

2. For Markdown content:
   - Preserve all Markdown syntax (##, *, `, [], etc.)
   - Maintain original line breaks and spacing
   - Keep code blocks (```) unchanged
   - Keep HTML tags unchanged
   - Keep YAML frontmatter unchanged

3. Translation quality requirements:
   - Maintain consistent terminology
   - Use formal technical writing style
   - Preserve original text structure and formatting
   - Ensure logical flow in the target language
   - Keep numbered lists and bullet points aligned

Only return the translated text without any explanations or additional content."#,
        target_lang.name()
    );

    // 使用 agent::generic 模块创建代理
    create_agent(
        provider_config,
        model,
        &system_prompt,
    )
}

#[cfg(test)]
mod tests {
    use super::*;
    use common::compose::make_empty_ctx;
    use dotenvy::dotenv;

    /// 测试辅助函数，创建翻译器并测试翻译
    async fn test_translator(provider: Provider) -> Result<(), String> {
        // 如果没有设置环境变量，则跳过测试
        let env_var = match provider {
            Provider::DeepSeek => "DEEPSEEK_API_KEY",
            Provider::OpenAI => "OPENAI_API_KEY",
            Provider::Gemini => "GEMINI_API_KEY",
        };

        if env::var(env_var).is_err() {
            return Err(format!("跳过测试：未设置 {} 环境变量", env_var));
        }

        // 获取API密钥
        let api_key = env::var(env_var).unwrap();

        // 创建提供商配置
        let provider_config = match provider {
            Provider::DeepSeek => ProviderConfig::DeepSeek {
                api_key,
                temperature: 0.2,
                max_tokens: Some(100),
            },
            Provider::OpenAI => ProviderConfig::OpenAI {
                api_key,
                base_url: None,
                temperature: 0.2,
                max_tokens: Some(100),
            },
            Provider::Gemini => ProviderConfig::Gemini {
                api_key,
                base_url: None,
                temperature: 0.2,
                max_tokens: Some(100),
            },
        };

        let translator = create_translator(provider_config, "", TargetLang::Zh);

        let input = "Hello, world!";
        let result = translator.run(input.to_string(), make_empty_ctx())
            .await
            .map_err(|e| format!("翻译失败: {}", e))?;

        println!("{:?} translation: {}", provider, result);

        if result.is_empty() {
            return Err("翻译结果为空".to_string());
        }

        Ok(())
    }

    #[tokio::test]
    async fn test_deepseek_translator() {
        dotenv().ok();

        match test_translator(Provider::DeepSeek).await {
            Ok(_) => {},
            Err(e) => println!("{}", e),
        }
    }

    #[tokio::test]
    async fn test_openai_translator() {
        dotenv().ok();

        match test_translator(Provider::OpenAI).await {
            Ok(_) => {},
            Err(e) => println!("{}", e),
        }
    }

    #[tokio::test]
    async fn test_gemini_translator() {
        dotenv().ok();

        match test_translator(Provider::Gemini).await {
            Ok(_) => {},
            Err(e) => println!("{}", e),
        }
    }

    #[test]
    fn test_target_lang() {
        assert_eq!(TargetLang::En.code(), "en");
        assert_eq!(TargetLang::Zh.code(), "zh");
        assert_eq!(TargetLang::Es.code(), "es");
        assert_eq!(TargetLang::Fr.code(), "fr");

        // 测试语言名称
        assert_eq!(TargetLang::En.name(), "English");
        assert_eq!(TargetLang::Zh.name(), "Chinese");
        assert_eq!(TargetLang::Ja.name(), "Japanese");
    }

    #[test]
    fn test_provider() {
        // 测试从字符串解析
        assert_eq!(Provider::from_str("deepseek").unwrap(), Provider::DeepSeek);
        assert_eq!(Provider::from_str("openai").unwrap(), Provider::OpenAI);
        assert_eq!(Provider::from_str("gemini").unwrap(), Provider::Gemini);
        assert_eq!(Provider::from_str("DEEPSEEK").unwrap(), Provider::DeepSeek); // 测试大小写不敏感
        assert!(Provider::from_str("unknown").is_err());
    }
}
